import os
import random
import json
import os
from datetime import datetime

class QuestionBankApp:
    def __init__(self, file_path, history_file='question_history.json'):
        """初始化题库应用"""
        self.file_path = file_path
        self.history_file = history_file
        self.questions = []
        self.questions_history = []
        self.load_resources()
    
    def load_resources(self):
        """加载题库和历史记录"""
        # 检查文件是否存在
        if not os.path.exists(self.file_path):
            print(f"文件不存在: {self.file_path}")
            return False
        
        # 加载题目
        print("正在加载题库...")
        self.questions = self.load_questions()
        
        if not self.questions:
            print("没有加载到题目")
            return False
        
        # 加载历史记录
        self.questions_history = self.load_progress()
        return True
    
    def load_questions(self):
        """加载并解析题库文件"""
        questions = []
        current_question = {}
        
        try:
            with open(self.file_path, 'r', encoding='utf-8') as f:
                for line in f:
                    line = line.strip()
                    if not line:
                        continue
                    
                    if line.startswith('[I]'):
                        # 如果当前已有题目，先保存
                        if current_question:
                            questions.append(current_question)
                            current_question = {}
                        # 开始新题目
                        current_question['id'] = line[3:]
                        current_question['options'] = {}
                    elif line.startswith('[Q]'):
                        current_question['question'] = line[3:]
                    elif line.startswith('[A]'):
                        current_question['options']['A'] = line[3:]
                    elif line.startswith('[B]'):
                        current_question['options']['B'] = line[3:]
                    elif line.startswith('[C]'):
                        current_question['options']['C'] = line[3:]
                    elif line.startswith('[D]'):
                        current_question['options']['D'] = line[3:]
                    elif line.startswith('[P]'):
                        # 题目结束，保存
                        if current_question:
                            questions.append(current_question)
                            current_question = {}
                # 处理文件末尾可能的最后一题
                if current_question:
                    questions.append(current_question)
        except UnicodeDecodeError:
            # 尝试使用其他编码
            try:
                with open(self.file_path, 'r', encoding='gbk') as f:
                    # 重新解析文件
                    questions = []
                    current_question = {}
                    for line in f:
                        line = line.strip()
                        if not line:
                            continue
                        
                        if line.startswith('[I]'):
                            if current_question:
                                questions.append(current_question)
                                current_question = {}
                            current_question['id'] = line[3:]
                            current_question['options'] = {}
                        elif line.startswith('[Q]'):
                            current_question['question'] = line[3:]
                        elif line.startswith('[A]'):
                            current_question['options']['A'] = line[3:]
                        elif line.startswith('[B]'):
                            current_question['options']['B'] = line[3:]
                        elif line.startswith('[C]'):
                            current_question['options']['C'] = line[3:]
                        elif line.startswith('[D]'):
                            current_question['options']['D'] = line[3:]
                        elif line.startswith('[P]'):
                            if current_question:
                                questions.append(current_question)
                                current_question = {}
                    if current_question:
                        questions.append(current_question)
            except Exception as e:
                print(f"读取文件失败: {e}")
                return []
        except Exception as e:
            print(f"读取文件失败: {e}")
            return []
        
        return questions
    
    def display_question(self, question, index, total):
        """显示题目和选项，选项顺序随机打乱且隐藏ABCD标识"""
        print(f"\n==== 第 {index}/{total} 题 ({question['id']}) ====")
        print(f"{question['question']}")
        
        # 提取选项列表
        options_list = list(question['options'].items())
        # 随机打乱选项顺序
        random.shuffle(options_list)
        
        # 显示打乱后的选项，用数字代替ABCD
        numbered_options = []
        a_number = None  # 用于存储A选项对应的数字
        for i, (key, option) in enumerate(options_list, 1):
            print(f"{i}. {option}")
            numbered_options.append((i, key))  # 保存数字与选项的对应关系
            if key == 'A':
                a_number = i  # 记录A选项对应的数字
        
        return numbered_options  # 返回数字与选项的对应关系
    
    def get_user_answer(self, numbered_options):
        """获取用户的答案输入，支持数字选择"""
        while True:
            answer = input("请输入你的答案 (1/2/3/4，输入q退出): ").upper()
            if answer == 'Q':
                return 'Q'
            if answer.isdigit():
                num = int(answer)
                if 1 <= num <= len(numbered_options):
                    # 找到对应的选项字母
                    for i, key in numbered_options:
                        if i == num:
                            return key
            print("输入无效，请重新输入")
    
    def save_progress(self):
        """保存答题历史"""
        try:
            with open(self.history_file, 'w', encoding='utf-8') as f:
                json.dump(self.questions_history, f, ensure_ascii=False, indent=2)
            return True
        except Exception as e:
            print(f"保存历史记录失败: {e}")
            return False
    
    def load_progress(self):
        """加载答题历史"""
        if not os.path.exists(self.history_file):
            return []
        try:
            with open(self.history_file, 'r', encoding='utf-8') as f:
                return json.load(f)
        except Exception as e:
            print(f"加载历史记录失败: {e}")
            return []
    
    def get_a_number(self, numbered_options):
        """获取正确答案A对应的数字"""
        for num, option_letter in numbered_options:
            if option_letter == 'A':
                return num
        return None
    
    def update_question_record(self, question_record):
        """更新题目记录"""
        # 检查是否已经存在该题的记录，如果有则更新
        updated = False
        for j, record in enumerate(self.questions_history):
            if record['id'] == question_record['id']:
                self.questions_history[j] = question_record
                updated = True
                break
        
        # 如果不存在则添加新记录
        if not updated:
            self.questions_history.append(question_record)
        
        # 保存进度
        self.save_progress()
    
    def get_unanswered_questions(self):
        """获取未回答过的题目"""
        answered_ids = {record['id'] for record in self.questions_history}
        return [q for q in self.questions if q['id'] not in answered_ids]
    
    def check_and_reset_history(self):
        """检查是否所有题目都已刷过，如果是则询问是否重置历史记录"""
        unanswered_questions = self.get_unanswered_questions()
        
        # 如果所有题目都刷过了，询问是否清零
        if not unanswered_questions:
            print("\n所有题目都已经刷过一遍了！")
            reset = input("是否清空历史记录重新开始？(y/n): ").lower()
            if reset == 'y':
                self.questions_history = []
                self.save_progress()
                print("历史记录已清空，现在开始重新刷题！")
                return self.questions.copy()
            else:
                print("将继续刷所有题目")
                return self.questions.copy()
        
        return unanswered_questions.copy()
    
    def start_quiz(self):
        """开始刷题模式"""
        # 让用户选择模式
        print("\n请选择刷题模式:")
        print("1. 顺序刷题")
        print("2. 随机刷题")
        
        mode = input("请输入选择 (1/2): ")
        
        # 获取要刷的题目列表
        questions_to_answer = self.check_and_reset_history()
        
        if mode == '2':
            # 随机排序题目
            random.shuffle(questions_to_answer)
        
        # 开始刷题
        for i, question in enumerate(questions_to_answer, 1):
            numbered_options = self.display_question(question, i, len(questions_to_answer))
            user_answer = self.get_user_answer(numbered_options)
            
            if user_answer == 'Q':
                # 用户退出
                break
            
            # 记录用户答案，默认正确答案为A
            correct_answer = 'A'  # 默认正确答案为A
            is_correct = user_answer == correct_answer
            
            question_record = {
                'id': question['id'],
                'question': question['question'],
                'options': question['options'],
                'user_answer': user_answer,
                'correct_answer': correct_answer,
                'is_correct': is_correct,
                'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            }
            
            # 显示答案判断
            if is_correct:
                print(f"✓ 正确! 正确答案是 {correct_answer}")
            else:
                print(f"✗ 错误! 正确答案是 {correct_answer}")
            
            # 查找并显示正确答案A对应的数字
            a_number = self.get_a_number(numbered_options)
            if a_number:
                print(f"正确答案A对应的数字是: {a_number}")
            
            # 更新记录
            self.update_question_record(question_record)
            
            print(f"你的答案 '{user_answer}' 已保存")
            input("按Enter键继续下一题...")
        
        # 显示本次刷题统计
        completed = i
        print(f"\n==== 本次刷题完成 ====")
        print(f"共完成 {completed} 道题目")
        print(f"历史记录中共有 {len(self.questions_history)} 道题目")
    
    def redo_wrong_questions(self):
        """错题重刷功能：重新作答历史记录中的错题"""
        if not self.questions_history:
            print("没有历史记录可供重刷")
            return
        
        # 筛选错题
        wrong_questions = [record for record in self.questions_history if not record.get('is_correct', False)]
        
        if not wrong_questions:
            print("恭喜！您没有错题需要重刷")
            return
        
        print(f"\n==== 错题重刷模式 ====")
        print(f"共有 {len(wrong_questions)} 道错题需要重刷")
        
        # 让用户选择重刷方式
        print("\n请选择重刷方式:")
        print("1. 按顺序重刷错题")
        print("2. 随机重刷错题")
        print("3. 返回主菜单")
        
        choice = input("请输入选择 (1/2/3): ").strip()
        
        if choice == '3':
            return
        
        # 根据错题ID从原题库中获取完整的题目信息
        wrong_ids = {record['id'] for record in wrong_questions}
        wrong_questions_full = [q for q in self.questions if q['id'] in wrong_ids]
        
        # 根据选择确定重刷顺序
        if choice == '2':
            random.shuffle(wrong_questions_full)
        
        correct_count = 0
        
        # 开始重刷错题
        for i, question in enumerate(wrong_questions_full, 1):
            print(f'\n==== 错题重刷 第 {i}/{len(wrong_questions_full)} 题 ({question["id"]}) ====')
            
            # 显示题目和选项（与普通刷题相同的体验）
            numbered_options = self.display_question(question, i, len(wrong_questions_full))
            user_answer = self.get_user_answer(numbered_options)
            
            if user_answer == 'Q':
                # 用户退出
                break
            
            # 记录用户答案，默认正确答案为A
            correct_answer = 'A'  # 默认正确答案为A
            is_correct = user_answer == correct_answer
            
            # 更新计数
            if is_correct:
                correct_count += 1
            
            # 创建或更新记录
            question_record = {
                'id': question['id'],
                'question': question['question'],
                'options': question['options'],
                'user_answer': user_answer,
                'correct_answer': correct_answer,
                'is_correct': is_correct,
                'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            }
            
            # 显示答案判断
            if is_correct:
                print(f"✓ 正确! 正确答案是 {correct_answer}")
                print("太好了，这道错题你已经掌握了！")
            else:
                print(f"✗ 错误! 正确答案是 {correct_answer}")
                print("还需要继续练习这道题哦！")
            
            # 查找并显示正确答案A对应的数字
            a_number = self.get_a_number(numbered_options)
            if a_number:
                print(f"正确答案A对应的数字是: {a_number}")
            
            # 更新记录
            self.update_question_record(question_record)
            
            print(f"你的答案 '{user_answer}' 已保存")
            input("按Enter键继续下一题...")
        
        # 显示本次错题重刷统计
        completed = i
        if completed > 0:
            accuracy = (correct_count / completed) * 100 if completed > 0 else 0
            print(f"\n==== 错题重刷完成 ====")
            print(f"共重刷 {completed} 道错题")
            print(f"重刷正确率: {accuracy:.2f}%")
            print(f"已掌握 {correct_count} 道错题")
            print(f"还有 {completed - correct_count} 道错题需要继续练习")
        
        input("按Enter键返回主菜单...")
    
    def simulate_exam(self):
        """模拟考试功能：随机抽选40个题目作答，作答不立即出结果，完成后统一出结果并保存错题"""
        print(f"\n==== 模拟考试模式 ====")
        print("将从题库中随机抽取40道题目进行模拟考试")
        print("作答过程中不会显示答案判断，完成后统一显示结果")
        
        # 从题库中随机选择40个题目
        if len(self.questions) < 40:
            print(f"警告：题库题目数量不足40道，将使用所有{len(self.questions)}道题目")
            exam_questions = self.questions.copy()
        else:
            exam_questions = random.sample(self.questions, 40)
        
        # 打乱题目的顺序
        random.shuffle(exam_questions)
        
        # 用于存储考试中的答案
        exam_answers = []
        
        print(f"\n考试开始，请开始作答 (输入q随时退出)")
        input("按Enter键开始第一个题目...")
        
        # 开始考试
        for i, question in enumerate(exam_questions, 1):
            # 清屏（简单的方式是打印多个空行）
            print('\n' * 50)
            
            # 显示题目
            numbered_options = self.display_question(question, i, len(exam_questions))
            
            # 获取用户答案
            user_answer = self.get_user_answer(numbered_options)
            
            if user_answer == 'Q':
                # 用户退出考试
                confirm = input("确定要退出考试吗？(y/n): ").lower()
                if confirm == 'y':
                    print("考试已退出，已完成的题目将被保存")
                    break
                else:
                    # 继续当前题目
                    i -= 1
                    continue
            
            # 记录答案但不显示结果
            a_number = self.get_a_number(numbered_options)
            
            exam_answers.append({
                'id': question['id'],
                'question': question['question'],
                'options': question['options'],
                'user_answer': user_answer,
                'correct_answer': 'A',  # 默认正确答案为A
                'is_correct': (user_answer == 'A'),
                'a_number': a_number,
                'numbered_options': numbered_options
            })
            
            # 不显示答案判断，直接进入下一题
            if i < len(exam_questions):
                input("按Enter键继续下一题...")
        
        # 考试结束，显示结果
        if exam_answers:
            print(f"\n==== 考试结果 ====")
            print(f"共完成 {len(exam_answers)} 道题目")
            
            # 计算正确率
            correct_count = sum(1 for ans in exam_answers if ans['is_correct'])
            accuracy = (correct_count / len(exam_answers)) * 100
            print(f"正确率: {accuracy:.2f}%")
            print(f"正确题目数: {correct_count}")
            print(f"错误题目数: {len(exam_answers) - correct_count}")
            
            # 显示详细结果
            show_detail = input("是否查看详细结果？(y/n): ").lower()
            if show_detail == 'y':
                for i, ans in enumerate(exam_answers, 1):
                    print(f"\n==== 第 {i} 题 ({ans['id']}) ====")
                    print(f"题目: {ans['question']}")
                    
                    # 显示选项和正确答案对应的数字
                    print("选项:")
                    for num, (key, option) in enumerate(ans['options'].items(), 1):
                        if key == 'A':
                            print(f"{num}. {option} (正确答案)")
                        else:
                            print(f"{num}. {option}")
                    
                    print(f"你的答案: {ans['user_answer']}")
                    status = '✓ 正确' if ans['is_correct'] else '✗ 错误'
                    print(f"答题状态: {status}")
                    print(f"正确答案A对应的数字是: {ans['a_number']}")
                    
                    if i < len(exam_answers):
                        input("按Enter键查看下一题...")
            
            # 保存错题记录
            print("\n正在保存考试记录...")
            for ans in exam_answers:
                # 创建符合历史记录格式的记录
                question_record = {
                    'id': ans['id'],
                    'question': ans['question'],
                    'options': ans['options'],
                    'user_answer': ans['user_answer'],
                    'correct_answer': ans['correct_answer'],
                    'is_correct': ans['is_correct'],
                    'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                }
                
                # 更新记录
                self.update_question_record(question_record)
            
            # 保存更新后的历史记录
            if self.save_progress():
                print("考试记录已保存")
            else:
                print("考试记录保存失败")
        
        input("按Enter键返回主菜单...")
    
    def review_questions(self):
        """复习已答题目"""
        if not self.questions_history:
            print("没有历史记录可供复习")
            return
        
        print(f"\n==== 复习模式 ====")
        print(f"共有 {len(self.questions_history)} 道题目可供复习")
        
        # 计算错题数量
        wrong_questions = [record for record in self.questions_history if not record.get('is_correct', False)]
        print(f"其中 {len(wrong_questions)} 道题目回答错误")
        
        # 让用户选择复习方式
        print("\n请选择复习方式:")
        print("1. 按顺序复习所有题目")
        print("2. 随机复习题目")
        print("3. 只复习错题(顺序)")
        print("4. 只复习错题(随机)")
        print("5. 返回主菜单")
        
        choice = input("请输入选择 (1/2/3/4/5): ")
        
        if choice == '5':
            return
        
        # 根据选择确定要复习的题目列表
        if choice == '3' or choice == '4':
            if not wrong_questions:
                print("没有错题可供复习")
                return
            review_list = wrong_questions.copy()
            if choice == '4':
                random.shuffle(review_list)
        else:
            review_list = self.questions_history.copy()
            if choice == '2':
                random.shuffle(review_list)
        
        for i, record in enumerate(review_list, 1):
            print(f"\n==== 复习第 {i}/{len(review_list)} 题 ({record['id']}) ====")
            print(f"题目: {record['question']}")
            
            # 提取选项列表并随机打乱
            options_list = list(record['options'].items())
            random.shuffle(options_list)
            
            # 显示打乱后的选项，用数字代替ABCD
            numbered_options = []
            a_number = None  # 用于存储A选项对应的数字
            for j, (key, option) in enumerate(options_list, 1):
                print(f"{j}. {option}")
                numbered_options.append((j, key))
                if key == 'A':
                    a_number = j  # 记录A选项对应的数字
            
            print(f"你的答案: {record['user_answer']}")
            # 显示正确答案（如果存在）
            if 'correct_answer' in record:
                print(f"正确答案: {record['correct_answer']}")
                # 显示答题是否正确
                if 'is_correct' in record:
                    status = '✓ 正确' if record['is_correct'] else '✗ 错误'
                    print(f"答题状态: {status}")
            
            # 查找并显示正确答案A对应的数字
            a_number = self.get_a_number(numbered_options)
            if a_number:
                print(f"正确答案A对应的数字是: {a_number}")
            
            print(f"答题时间: {record['timestamp']}")
            
            # 允许用户更新答案
            update = input("是否更新答案? (y/n，输入q退出复习): ").lower()
            if update == 'q':
                break
            if update == 'y':
                new_answer = self.get_user_answer(numbered_options)
                if new_answer:
                    record['user_answer'] = new_answer
                    # 更新答题是否正确的信息
                    if 'correct_answer' in record:
                        record['is_correct'] = (new_answer == record['correct_answer'])
                        # 显示更新后的答题状态
                        status = '✓ 正确' if record['is_correct'] else '✗ 错误'
                        print(f"答题状态已更新: {status}")
                    record['timestamp'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                    print("答案已更新")
        
        # 保存更新后的历史记录
        self.save_progress()
    
    def show_statistics(self):
        """显示统计信息"""
        if not self.questions_history:
            print("没有统计信息可供查看")
        else:
            print(f"\n==== 统计信息 ====")
            print(f"总答题数: {len(self.questions_history)}")
            
            # 计算正确率
            correct_count = sum(1 for record in self.questions_history if record.get('is_correct', False))
            if len(self.questions_history) > 0:
                accuracy = (correct_count / len(self.questions_history)) * 100
                print(f"正确率: {accuracy:.2f}%")
                print(f"正确题目数: {correct_count}")
                print(f"错误题目数: {len(self.questions_history) - correct_count}")
            
            # 计算答题率
            answer_rate = (len(self.questions_history) / len(self.questions)) * 100 if len(self.questions) > 0 else 0
            print(f"答题率: {answer_rate:.2f}%")
            
            # 显示最近答题时间
            recent_timestamp = max(record['timestamp'] for record in self.questions_history)
            print(f"最近答题时间: {recent_timestamp}")
        input("按Enter键返回主菜单...")
    
    def display_menu(self):
        """显示主菜单"""
        print(f"\n==== A类题库刷题软件 ====")
        print(f"已加载 {len(self.questions)} 道题目")
        print(f"历史记录中有 {len(self.questions_history)} 道题目")
        print("请选择操作:")
        print("1. 开始刷题")
        print("2. 复习已答题目")
        print("3. 查看统计信息")
        print("4. 退出软件")
        print("5. 模拟考试")
        print("6. 错题重刷")
    
    def run(self):
        """运行主程序"""
        if not self.load_resources():
            return
        
        while True:
            self.display_menu()
            choice = input("请输入选择 (1-6): ").strip()
            
            if choice == '4':
                print("感谢使用刷题软件！")
                break
            elif choice == '1':
                self.start_quiz()
            elif choice == '2':
                self.review_questions()
            elif choice == '3':
                self.show_statistics()
            elif choice == '5':
                self.simulate_exam()
            elif choice == '6':
                self.redo_wrong_questions()
            elif choice:  # 只有当用户输入了内容但不是有效选项时，才显示错误提示
                print("输入无效，请重新输入")


def main():
    """主函数"""
    # 题库文件路径
    file_path = r"c:\Users\chenx\Desktop\Code\python\shuati\TXT题库包(v20211022)\A类题库(v20211022).txt"
    
    # 创建并运行应用
    app = QuestionBankApp(file_path)
    app.run()


if __name__ == "__main__":
    main()